✨ Elixir 1.17's new Date.shift/2 🕐

Notes

Elixir 1.17 introduced a new shift/2 function to work with dates and date times that I think is pretty cool.

Up until now, when we want to change a date, we’d likely use Date.add/2 – that would add days to the given date:

today = Date.utc_today()
Date.add(today, 1)
# => tomorrow

But what if we want to add weeks, months, or years?

Date.shift/2 has our back:

today = Date.utc_today()
Date.shift(today, day: 1)
# => tomorrow

Date.shift(today, week: 1)
# => next week

Date.shift(today, month: 1)
# => next month

Date.shift(today, year: 1)
# => next year

But here’s the important thing to remember:

It’s not an arithmetic operation

Why does that matter? Take this example:

end_of_jan = Date.new!(2024, 01, 31)

end_of_feb = Date.shift(end_of_jan, month: 1)
# => ~D[2024-02-29]

We shift the end of January by a month and we get the end of February. That’s awesome! It knows about calendars! It didn’t just add 30 days in some arithmetic operation.

But by the same token… what should it do when it shifts back a month?

end_of_feb = ~D[2024-02-29]
not_end_of_jan = Date.shift(end_of_feb, month: -1)
# => ~D[2024-01-29]

Well… that’s slightly more surprising, right? It didn’t shift back to the 31st. It shifted by to the 29th.

In other words, because we’re not doing arithmetic, the order of operations matters: shifting a month ahead and a month back won’t necessarily give you the starting date.

I think this is be a cool helper, but you have to keep that in mind.

Want the latest Elixir Streams in your inbox?

    No spam. Unsubscribe any time.